﻿using System;
using System.Linq;
using System.Reflection;
using System.Web.Mvc;
using Castle.Facilities.FactorySupport;
using Castle.Facilities.WcfIntegration;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using ScrumBox.DataAccess;
using ScrumBox.DataAccess.Repositories;
using ScrumBox.Model;

namespace ScrumBox.Web.Components
{
    public class ScrumBoxContainer : WindsorContainer
    {
        public ScrumBoxContainer()
        {
            AddFacility<WcfFacility>();
            AddFacility<FactorySupportFacility>();

            Register
            (
                Component.For<IHttpContextProvider>().ImplementedBy<HttpContextProvider>().Named("IHttpContextProvider"),
                Component.For<ISessionBuilder>().ImplementedBy<HybridSessionBuilder>().Named("ISessionBuilder"),
                Component.For<IProjectRepository>().ImplementedBy<ProjectRepository>().Named("IProjectRepository"),
                Component.For<ISprintRepository>().ImplementedBy<SprintRepository>().Named("ISprintRepository"),
                
                AllTypes.Of<Controller>().FromAssembly(Assembly.GetExecutingAssembly())
                .Configure
                (
                    component => component.LifeStyle.Transient.Named(component.Implementation.Name.ToLower())
                )
            );
        }

        public void RegisterControllers()
        {
            // Choosing types if they have a specific attribute (courtesy of LINQ) 
            Kernel.Register
            (
                  AllTypes
                  .Of<Controller>()
                  .Pick
                  (
                      from type in Assembly.GetExecutingAssembly().GetExportedTypes()
                      where type.IsDefined(typeof(SerializableAttribute), true)
                      select type
                  )
                  .Configure
                  (
                    component => component.LifeStyle.Transient.Named(component.Implementation.Name.ToLower())
                  )
            );
        }
    }
}